package com.lzq.config;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.atomic.AtomicInteger;

import javax.sql.DataSource;

import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

@Profile("test")
@Configuration
@ComponentScan("com.lzq")
public class TestDbConfig {
	
	public TestDbConfig() {
		System.out.println("@Configuration TestConfig created ");
	}
	@Bean
	public PlatformTransactionManager transactionManager() {
		System.out.println(TestDbConfig.class + "transactionManager created ");
		DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
		transactionManager.setDataSource(dataSource());
		return transactionManager;
	}
	@Bean
	public DataSource dataSource() {
		DataSource mockedDataSrc = Mockito.mock(DataSource.class);
		Connection conn = Mockito.mock(Connection.class);
		Statement state = Mockito.mock(Statement.class);
		ResultSet rs = Mockito.mock(ResultSet.class);
		//mock数据
		Object[][] rowDatas = { { 1L, "user-1", 90 }, { 2L, "user-2", 91 } };
		final AtomicInteger idx = new AtomicInteger(0);
		final MockRow row = new MockRow();

		try {
			Mockito.when(mockedDataSrc.getConnection()).thenReturn(conn);
			Mockito.when(conn.createStatement()).thenReturn(state);
			Mockito.when(state.executeQuery(Mockito.anyString())).thenReturn(rs);
			// 构造虚拟的resultSet,当执行resultSet.next()时候，设置下一行的数据
			Mockito.doAnswer((invocation)->{
				int index = idx.getAndIncrement();
				if (rowDatas.length <= index) {
					return false;
				}
				Object[] current = rowDatas[index];
				System.out.println("Mock:设置第"+index+"行的结果");
				row.setCurrentRowData(current);
				return true;
			}).when(rs).next();
			
			
			// 构造虚拟的resultSet,当执行resultSet.getObject(int)时候，设置要返回的数据
			Mockito.doAnswer((invocation)->{
					Object[] args = invocation.getArguments();
					int cursor = ((Integer) args[0]).intValue();
					System.out.println("Mock:获取第"+cursor+"列的值");
					return row.getColumn(cursor);
			}).when(rs).getObject(Mockito.anyInt());
			
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return mockedDataSrc;
	}

	
	static class MockRow {
		Object[] rowData;

		public void setCurrentRowData(Object[] rowData) {
			this.rowData = rowData;
		}

		public Object getColumn(int idx) {
			return rowData[idx - 1];
		}
	}

}
